package org.budo.mybatis.dao.statement.builder.util;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Map;

import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.session.Configuration;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;

/**
 * @author lmw
 */
public class StatementBuilderUtil {
    private static final Logger log = Slf4j.getLogger();

    private static final String STATEMENT_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" //
            + "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n" //
            + "<mapper namespace=\"{{NAMESPACE}}\">\n" //
            + "{{STATEMENT}}\n" //
            + "</mapper>";

    public static void parseXmlMapper(Configuration configuration, String namespace, String statementXml) {
        String xml = STATEMENT_TEMPLATE.replace("{{NAMESPACE}}", namespace) //
                .replace("{{STATEMENT}}", statementXml);

        log.info("#29 parseXmlMapper\n" + xml);

        InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
        String resource = "" + Math.random();
        Map<String, XNode> sqlFragments = configuration.getSqlFragments();

        try {
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(inputStream, configuration, resource, sqlFragments);
            xmlMapperBuilder.parse();
        } catch (Throwable e) {
            if (("" + e).contains("Mapped Statements collection already contains value for")) {
                log.error("#40 parseXmlMapper error, namespace=" + namespace + ", statementXml=" + statementXml + ", e=" + e);
                return;
            }

            throw new RuntimeException("#44 parseXmlMapper error, namespace=" + namespace + ", statementXml=" + statementXml, e);
        }
    }
}